package com.example.recordingpen_datacollection.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.recordingpen_datacollection.Utils.DateUtils.TimeJudgeUtils;
import com.example.recordingpen_datacollection.Utils.String.StringUtils;
import com.example.recordingpen_datacollection.Utils.http.BDokHttpUtil;
import com.example.recordingpen_datacollection.entity.BaiduKey;
import com.example.recordingpen_datacollection.entity.Vo.BaiduKeyVo;
import com.example.recordingpen_datacollection.mapper.BaiduKeyMapper;
import com.example.recordingpen_datacollection.redisService.RedisService;
import com.example.recordingpen_datacollection.result.exceptionhandler.JWException;
import com.example.recordingpen_datacollection.service.BaiduKeyService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.List;

import static com.example.recordingpen_datacollection.config.constant.ConstantName.SQLSERVER_BAIDU_KEY;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author xg
 * @since 2024-06-14
 */
@Service
public class BaiduKeyServiceImpl extends ServiceImpl<BaiduKeyMapper, BaiduKey> implements BaiduKeyService {
    @Autowired
    private RedisService redisService;

    @Override
    public synchronized String BDtoken() {
        List<BaiduKey> list = null;
        if(redisService.getKeyData("SQLSERVER_BAIDU_KEY")){
            list = (List<BaiduKey>) redisService.getValue("SQLSERVER_BAIDU_KEY");
        } else {
            QueryWrapper wrapper = new QueryWrapper();
            wrapper.ne("frequency_limit",0);
            list = this.list(wrapper);
            redisService.setValue("SQLSERVER_BAIDU_KEY",list);
        }
        String kerStr = null;
        if(list == null || list.size()<=0){
            return kerStr;
        }
        for (int i = 0; i < list.size(); i++) {
            //判断当前的key 的使用位置
            if(list.get(i).getSign() == 1){
                //判断是否到达使用临界值   未达到临界值
                if(list.get(i).getNumberOfUse() < list.get(i).getFrequencyLimit()){
                    //可以提前为一个方法 -----------------------------------------------------1
                    //获取当前时间
                    BaiduKey baiduKeyForI = list.get(i);
                    String nowDate = TimeJudgeUtils.getNowDate();
                    Date expirationTime = baiduKeyForI.getExpirationTime();
                    boolean time = false;
                    //比较当前时间是否大于过期时间
                    if(expirationTime != null){
                        time = TimeJudgeUtils.judgeTime(nowDate, TimeJudgeUtils.strData(expirationTime));
                    }
                    if( StringUtils.isEmpty(baiduKeyForI.getKeyValue()) || time){
                        String bDtokenData = null;
                        try {
                            bDtokenData = BDokHttpUtil.getBDtoken(baiduKeyForI.getBaiduUrl());
                        } catch (IOException e) {
                            throw new JWException(500,"请求百度令牌失败");
                        }
                        JSONObject jsonObject = JSON.parseObject(bDtokenData);

                        // 从JSONObject中提取值
                        String access_token = jsonObject.getString("access_token");
                        int expires_in = jsonObject.getIntValue("expires_in")-(360); //秒数

                        String s = TimeJudgeUtils.addSecondTime(TimeJudgeUtils.getNowDate(), (expires_in));
                        //修改数据 添加key——value
                        {

                            BaiduKey baiduKey = new BaiduKey();
                            baiduKey.setKeyid(baiduKeyForI.getKeyid());
                            baiduKey.setKeyValue(access_token);
                            baiduKey.setNumberOfUse(baiduKeyForI.getNumberOfUse()+1);
                            baiduKey.setExpirationTime(TimeJudgeUtils.strData(s));
                            baiduKey.setTotalCites(baiduKeyForI.getTotalCites()+1);
//                            是否下移标志位
                            boolean update = redisService.ModifyingDataConsistency_BAIDUKEY(baiduKey);
                            if(!update){
                                return null;
                            }
                        }
                        return access_token;
                    } else {        //存在Value  当前时间小于 过期时间情况下
                        {

                            BaiduKey baiduKey = new BaiduKey();
                            baiduKey.setKeyid(baiduKeyForI.getKeyid());
                            baiduKey.setNumberOfUse(baiduKeyForI.getNumberOfUse()+1);
                            baiduKey.setTotalCites(baiduKeyForI.getTotalCites()+1);
                            baiduKey.setSign(1);
//                            是否下移标志位
                            boolean update = redisService.ModifyingDataConsistency_BAIDUKEY(baiduKey);
                            return baiduKeyForI.getKeyValue();
                        }
                    }
                } else {        //达到临界值时
//                    //修改当前临界值为0
//                    {
//                        BaiduKey baiduKey = new BaiduKey();
//                        baiduKey.setKeyid(list.get(i).getKeyid());
//                        baiduKey.setSign(0);
//                        baiduKey.setNumberOfUse(0);
////                            是否下移标志位
//                        boolean update = redisService.ModifyingDataConsistency_BAIDUKEY(baiduKey);
//                    }

                    //判断是否为最后一个

                    if( (i+1)<list.size() ){
                        BaiduKey baiduKeyForI = list.get(i + 1);
                        //可以提前为一个方法 -----------------------------------------------------2
                        String nowDate = TimeJudgeUtils.getNowDate();
                        Date expirationTime = baiduKeyForI.getExpirationTime();
                        boolean time = false;
                        //比较当前时间是否大于过期时间
                        if(expirationTime != null){
                            time = TimeJudgeUtils.judgeTime(nowDate, TimeJudgeUtils.strData(expirationTime));
                        }
                        if(StringUtils.isEmpty(baiduKeyForI.getKeyValue()) || time) {
                            String bDtokenData = null;
                            String access_token = null;
                            String s = null;
                            try {
                                bDtokenData = BDokHttpUtil.getBDtoken(baiduKeyForI.getBaiduUrl());
                                JSONObject jsonObject = JSON.parseObject(bDtokenData);

                                // 从JSONObject中提取值
                                access_token = jsonObject.getString("access_token");
                                int expires_in = jsonObject.getIntValue("expires_in") - (360); //秒数
                                s = TimeJudgeUtils.addSecondTime(TimeJudgeUtils.getNowDate(), (expires_in));
                            } catch (IOException e) {
                                throw new JWException(500, "请求百度令牌失败");

                            } finally {
                                //修改数据 添加key——value
                                {

                                    BaiduKey baiduKey = new BaiduKey();
                                    baiduKey.setKeyid(baiduKeyForI.getKeyid());
                                    baiduKey.setKeyValue(access_token);
                                    baiduKey.setNumberOfUse(baiduKeyForI.getNumberOfUse() +1);
                                    if(StringUtils.isNotEmpty(s)){
                                        baiduKey.setExpirationTime(TimeJudgeUtils.strData(s));
                                    }

                                    baiduKey.setTotalCites(baiduKeyForI.getTotalCites()+1);
                                    baiduKey.setSign(1);
                                    //修改当前临界值为0
                                    boolean b = setBaiduKeySign(list.get(i).getKeyid());
//                            是否下移标志位
                                    boolean update = redisService.ModifyingDataConsistency_BAIDUKEY(baiduKey);

                                }
                            }


                            return access_token;
                        } else {        //存在Value  当前时间小于 过期时间情况下
                            {

                                BaiduKey baiduKey = new BaiduKey();
                                baiduKey.setKeyid(baiduKeyForI.getKeyid());
                                baiduKey.setNumberOfUse(baiduKeyForI.getNumberOfUse()+1);
                                baiduKey.setTotalCites(baiduKeyForI.getTotalCites()+1);
                                baiduKey.setSign(1);

                                //修改当前临界值为0
                                boolean b = setBaiduKeySign(list.get(i).getKeyid());
//                            是否下移标志位
                                boolean update = redisService.ModifyingDataConsistency_BAIDUKEY(baiduKey);
                                return baiduKeyForI.getKeyValue();
                            }
                        }

                    }else {
                        BaiduKey baiduKeyForI = list.get(0);
                        //可以提前为一个方法 -----------------------------------------------------3
                        String nowDate = TimeJudgeUtils.getNowDate();
                        Date expirationTime = baiduKeyForI.getExpirationTime();
                        boolean time = false;
                        //比较当前时间是否大于过期时间
                        if(expirationTime != null){
                            time = TimeJudgeUtils.judgeTime(nowDate, TimeJudgeUtils.strData(expirationTime));
                        }
                        if(baiduKeyForI.getKeyValue() == null || time) {
                            String bDtokenData = null;
                            String access_token = null;
                            String s = null;
                            try {
                                bDtokenData = BDokHttpUtil.getBDtoken(baiduKeyForI.getBaiduUrl());
                                JSONObject jsonObject = JSON.parseObject(bDtokenData);

                                // 从JSONObject中提取值
                                access_token = jsonObject.getString("access_token");
                                int expires_in = jsonObject.getIntValue("expires_in") - (360); //秒数

                                s = TimeJudgeUtils.addSecondTime(TimeJudgeUtils.getNowDate(), (expires_in / 1000));
                            } catch (IOException e) {
                                throw new JWException(500, "请求百度令牌失败");
                            } finally {
                                //修改数据 添加key——value
                                {

                                    BaiduKey baiduKey = new BaiduKey();
                                    baiduKey.setKeyid(baiduKeyForI.getKeyid());
                                    baiduKey.setKeyValue(access_token);
                                    baiduKey.setNumberOfUse(baiduKeyForI.getNumberOfUse() + 1);
                                    if(StringUtils.isNotEmpty(s)){
                                        baiduKey.setExpirationTime(TimeJudgeUtils.strData(s));
                                    }
                                    baiduKey.setTotalCites(baiduKeyForI.getTotalCites()+1);
                                    baiduKey.setSign(1);
                                    //修改当前临界值为0
                                    boolean b = setBaiduKeySign(list.get(i).getKeyid());
//                            是否下移标志位
                                    boolean update = redisService.ModifyingDataConsistency_BAIDUKEY(baiduKey);
                                }
                            }


                            return access_token;
                        } else {        //存在Value  当前时间小于 过期时间情况下
                            {

                                BaiduKey baiduKey = new BaiduKey();
                                baiduKey.setKeyid(baiduKeyForI.getKeyid());
                                baiduKey.setNumberOfUse(baiduKeyForI.getNumberOfUse()+1);
                                baiduKey.setTotalCites(baiduKeyForI.getTotalCites()+1);
                                baiduKey.setSign(1);
                                //修改当前临界值为0
                                boolean b = setBaiduKeySign(list.get(i).getKeyid());

//                            是否下移标志位
                                boolean update = redisService.ModifyingDataConsistency_BAIDUKEY(baiduKey);
                                return baiduKeyForI.getKeyValue();
                            }
                        }
                    }

                }
            }

        }

        return null;
    }



    private boolean setBaiduKeySign(Integer keyid){
        //修改当前临界值为0
            BaiduKey baiduKey = new BaiduKey();
            baiduKey.setKeyid(keyid);
            baiduKey.setSign(0);
            baiduKey.setNumberOfUse(0);
//                            是否下移标志位
            boolean update = redisService.ModifyingDataConsistency_BAIDUKEY(baiduKey);
            return update;
    }

    @Override
    public synchronized String payBDtoken() {
        List<BaiduKey> list = null;
        if(redisService.getKeyData("SQLSERVER_BAIDU_KEY")){
            list = (List<BaiduKey>) redisService.getValue("SQLSERVER_BAIDU_KEY");
        } else {
            QueryWrapper wrapper = new QueryWrapper();
            wrapper.ne("frequency_limit",0);
            list = this.list(wrapper);
            redisService.setValue("SQLSERVER_BAIDU_KEY",list);
        }
        for (int i = 0; i < list.size(); i++) {
            BaiduKey baiduKeyPay = list.get(i); //s=收费
            if(baiduKeyPay.getKeyid()==1){
                String nowDate = TimeJudgeUtils.getNowDate();
                Date expirationTime = baiduKeyPay.getExpirationTime();
                boolean time = false;
                //比较当前时间是否大于过期时间
                if(expirationTime != null){
                    time = TimeJudgeUtils.judgeTime(nowDate, TimeJudgeUtils.strData(expirationTime));
                }
                if(StringUtils.isEmpty(baiduKeyPay.getKeyValue()) || time) {
                    String bDtokenData = null;
                    String access_token = null;
                    String s = null;
                    try {
                        bDtokenData = BDokHttpUtil.getBDtoken(baiduKeyPay.getBaiduUrl());
                        JSONObject jsonObject = JSON.parseObject(bDtokenData);

                        // 从JSONObject中提取值
                        access_token = jsonObject.getString("access_token");
                        int expires_in = jsonObject.getIntValue("expires_in") - (360); //秒数
                        s = TimeJudgeUtils.addSecondTime(TimeJudgeUtils.getNowDate(), (expires_in));
                    } catch (IOException e) {
                        throw new JWException(500, "请求百度令牌失败");

                    } finally {
                        //修改数据 添加key——value
                        {
                            BaiduKey baiduKey = new BaiduKey();
                            baiduKey.setKeyid(baiduKeyPay.getKeyid());
                            baiduKey.setKeyValue(access_token);
                            baiduKey.setNumberOfUse(baiduKeyPay.getNumberOfUse() +1);
                            if(StringUtils.isNotEmpty(s)){
                                baiduKey.setExpirationTime(TimeJudgeUtils.strData(s));
                            }
                            baiduKey.setTotalCites(baiduKeyPay.getTotalCites()+1);
                            //修改当前临界值为0
//                            是否下移标志位
                            boolean update = redisService.ModifyingDataConsistency_BAIDUKEY(baiduKey);

                        }
                    }
                    return access_token;
                } else {        //存在Value  当前时间小于 过期时间情况下
                    {

                        BaiduKey baiduKey = new BaiduKey();
                        baiduKey.setKeyid(baiduKeyPay.getKeyid());
                        baiduKey.setNumberOfUse(baiduKeyPay.getNumberOfUse()+1);
                        baiduKey.setTotalCites(baiduKeyPay.getTotalCites()+1);
//                            是否下移标志位
                        boolean update = redisService.ModifyingDataConsistency_BAIDUKEY(baiduKey);
                        return baiduKeyPay.getKeyValue();
                    }
                }
            }
        }
        return null;
    }

    @Override
    public boolean setBaidukey(BaiduKeyVo baiduKeyVo) {
        BaiduKey baiduKey = new BaiduKey();
        baiduKey.setArrange(baiduKeyVo.getArrange());
        baiduKey.setBaiduUrl(baiduKeyVo.getBaiduUrl());
        baiduKey.setKeyName(baiduKeyVo.getKeyName());
        baiduKey.setFrequencyLimit(baiduKeyVo.getFrequencyLimit());
        boolean save = this.save(baiduKey);
        return save;
    }



    //数据库同步
    @Scheduled(cron = "0 0 0 * * ?")
    public void scheduleTask() {
        // 定时任务的逻辑
        Object value = redisService.getValue(SQLSERVER_BAIDU_KEY);
        List<BaiduKey> baiduKeys = (List<BaiduKey>) value;
        boolean b = this.updateBatchById(baiduKeys);

    }
    @Override
    public boolean sqlScheduleTask() {
        // 定时任务的逻辑
        Object value = redisService.getValue(SQLSERVER_BAIDU_KEY);
        List<BaiduKey> baiduKeys = (List<BaiduKey>) value;
        boolean b = this.updateBatchById(baiduKeys);
        return b;

    }



}
